//
// Created by Snow on 2023/3/30.
//
#include<cstdio>
#include <cstdlib>
#define MaxSize 50
typedef char ElemType;
typedef struct node
{
    ElemType data;//数据元素
    struct node *lchild;//指向左孩子结点
    struct node *rchild;//指向右孩子结点
}BTNode;
//创建二叉树
void CreatBTree(BTNode *&b,const char *str)
{
    BTNode *St[MaxSize],*p;//st数组作为顺序栈
    int top=-1,k,j=0;//top为栈顶指针
    char ch;
    b=nullptr;//初始时二叉链为空
    ch=str[j];
    while(ch!='\0')//遍历str中的每一个字符
    {
        switch(ch)
        {
            case '(':top++;St[top]=p;k=1;break;//开始处理左孩子结点
            case ')':top--;break;//栈顶结点的子树处理完毕
            case ',':k=2;break;//开始处理右孩子结点
            default:
                p=(BTNode*)malloc(sizeof(BTNode));//创建一个结点，有p指向他
                p->data=ch;//存放结点值
                p->lchild=p->rchild=nullptr;//左、右指针都设置为空
                if(b==nullptr)//若尚未建立根结点
                    b=p;//p所指向的结点作为根节点
                else//已建立二叉树根节点
                {
                    switch(k)
                    {
                        case 1:St[top]->lchild=p;break;//新建结点作为栈顶结点的左孩子
                        case 2:St[top]->rchild=p;break;//新建结点作为栈顶结点的右孩子
                    }
                }
        }
        j++;
        ch=str[j];//继续遍历str
    }
}
//销毁二叉树
void DestroyBTree(BTNode *&b)
{
    if(b!=nullptr)
    {
        DestroyBTree(b->lchild);
        DestroyBTree(b->rchild);
        free(b);
    }
}
//查找结点
BTNode *FindNode(BTNode *b,ElemType x)
{
    BTNode *p;
    if(b==nullptr)
        return nullptr;
    else if(b->data==x)
        return b;
    else
    {
        p=FindNode(b->lchild,x);
        if(p!=nullptr)
            return p;
        else
            return FindNode(b->rchild,x);
    }
}
//找孩子结点
BTNode *LchildNode(BTNode *p)
{
    return p->lchild;
}
BTNode *RchildNode(BTNode *p)
{
    return p->rchild;
}
//求高度
int BTHeight(BTNode *b)
{
    int lchildh,rchildh;
    if(b==nullptr)
        return 0;//空树的高度为0
    else
    {
        lchildh=BTHeight(b->lchild);//求左子树的高度
        rchildh=BTHeight(b->rchild);//求右子树的高度
        return((lchildh>rchildh)?(lchildh+1):(rchildh+1));
    }
}
//输出二叉树
void DispBTree(BTNode *b)
{
    if(b!=nullptr)
    {
        printf("%c",b->data);
        if(b->lchild!=nullptr||b->rchild!=nullptr)
        {
            printf("(");//有孩子结点时才输出"("
            DispBTree(b->lchild);//递归输出左子树
            if(b->rchild!=nullptr)
                printf(",");//有右孩子才输出","
            DispBTree(b->rchild);//递归输出右子树
            printf(")");//有孩子结点时才输出")"
        }
    }
}
int main()
{
    BTNode *b;
    CreatBTree(b,"A(B(D(,G)),C(E,F))");
    DispBTree(b);
    printf("\n%d\n", BTHeight(b));
    DispBTree(LchildNode(b));
    printf("\n");
    DispBTree(RchildNode(b));
    DestroyBTree(b);
}